home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 127 / PC Guia 127.iso / Software / Produtividade / OpenOffice.org 2.0.1 / openofficeorg4.cab / test_csv.py < prev    next >
Text File  |  2005-11-19  |  27KB  |  716 lines

  1. # -*- coding: iso-8859-1 -*-
  2. # Copyright (C) 2001,2002 Python Software Foundation
  3. # csv package unit tests
  4.  
  5. import sys
  6. import unittest
  7. from StringIO import StringIO
  8. import csv
  9. import gc
  10. from test import test_support
  11.  
  12. class Test_Csv(unittest.TestCase):
  13.     """
  14.     Test the underlying C csv parser in ways that are not appropriate
  15.     from the high level interface. Further tests of this nature are done
  16.     in TestDialectRegistry.
  17.     """
  18.     def test_reader_arg_valid(self):
  19.         self.assertRaises(TypeError, csv.reader)
  20.         self.assertRaises(TypeError, csv.reader, None)
  21.         self.assertRaises(AttributeError, csv.reader, [], bad_attr = 0)
  22.         self.assertRaises(csv.Error, csv.reader, [], 'foo')
  23.         class BadClass:
  24.             def __init__(self):
  25.                 raise IOError
  26.         self.assertRaises(IOError, csv.reader, [], BadClass)
  27.         self.assertRaises(TypeError, csv.reader, [], None)
  28.         class BadDialect:
  29.             bad_attr = 0
  30.         self.assertRaises(AttributeError, csv.reader, [], BadDialect)
  31.  
  32.     def test_writer_arg_valid(self):
  33.         self.assertRaises(TypeError, csv.writer)
  34.         self.assertRaises(TypeError, csv.writer, None)
  35.         self.assertRaises(AttributeError, csv.writer, StringIO(), bad_attr = 0)
  36.  
  37.     def _test_attrs(self, obj):
  38.         self.assertEqual(obj.dialect.delimiter, ',')
  39.         obj.dialect.delimiter = '\t'
  40.         self.assertEqual(obj.dialect.delimiter, '\t')
  41.         self.assertRaises(TypeError, delattr, obj.dialect, 'delimiter')
  42.         self.assertRaises(TypeError, setattr, obj.dialect,
  43.                           'lineterminator', None)
  44.         obj.dialect.escapechar = None
  45.         self.assertEqual(obj.dialect.escapechar, None)
  46.         self.assertRaises(TypeError, delattr, obj.dialect, 'quoting')
  47.         self.assertRaises(TypeError, setattr, obj.dialect, 'quoting', None)
  48.         obj.dialect.quoting = csv.QUOTE_MINIMAL
  49.         self.assertEqual(obj.dialect.quoting, csv.QUOTE_MINIMAL)
  50.  
  51.     def test_reader_attrs(self):
  52.         self._test_attrs(csv.reader([]))
  53.  
  54.     def test_writer_attrs(self):
  55.         self._test_attrs(csv.writer(StringIO()))
  56.  
  57.     def _write_test(self, fields, expect, **kwargs):
  58.         fileobj = StringIO()
  59.         writer = csv.writer(fileobj, **kwargs)
  60.         writer.writerow(fields)
  61.         self.assertEqual(fileobj.getvalue(),
  62.                          expect + writer.dialect.lineterminator)
  63.  
  64.     def test_write_arg_valid(self):
  65.         self.assertRaises(csv.Error, self._write_test, None, '')
  66.         self._write_test((), '')
  67.         self._write_test([None], '""')
  68.         self.assertRaises(csv.Error, self._write_test,
  69.                           [None], None, quoting = csv.QUOTE_NONE)
  70.         # Check that exceptions are passed up the chain
  71.         class BadList:
  72.             def __len__(self):
  73.                 return 10;
  74.             def __getitem__(self, i):
  75.                 if i > 2:
  76.                     raise IOError
  77.         self.assertRaises(IOError, self._write_test, BadList(), '')
  78.         class BadItem:
  79.             def __str__(self):
  80.                 raise IOError
  81.         self.assertRaises(IOError, self._write_test, [BadItem()], '')
  82.  
  83.     def test_write_bigfield(self):
  84.         # This exercises the buffer realloc functionality
  85.         bigstring = 'X' * 50000
  86.         self._write_test([bigstring,bigstring], '%s,%s' % \
  87.                          (bigstring, bigstring))
  88.  
  89.     def test_write_quoting(self):
  90.         self._write_test(['a','1','p,q'], 'a,1,"p,q"')
  91.         self.assertRaises(csv.Error,
  92.                           self._write_test,
  93.                           ['a','1','p,q'], 'a,1,"p,q"',
  94.                           quoting = csv.QUOTE_NONE)
  95.         self._write_test(['a','1','p,q'], 'a,1,"p,q"',
  96.                          quoting = csv.QUOTE_MINIMAL)
  97.         self._write_test(['a','1','p,q'], '"a",1,"p,q"',
  98.                          quoting = csv.QUOTE_NONNUMERIC)
  99.         self._write_test(['a','1','p,q'], '"a","1","p,q"',
  100.                          quoting = csv.QUOTE_ALL)
  101.  
  102.     def test_write_escape(self):
  103.         self._write_test(['a','1','p,q'], 'a,1,"p,q"',
  104.                          escapechar='\\')
  105. # FAILED - needs to be fixed [am]:
  106. #        self._write_test(['a','1','p,"q"'], 'a,1,"p,\\"q\\"',
  107. #                         escapechar='\\', doublequote = 0)
  108.         self._write_test(['a','1','p,q'], 'a,1,p\\,q',
  109.                          escapechar='\\', quoting = csv.QUOTE_NONE)
  110.  
  111.     def test_writerows(self):
  112.         class BrokenFile:
  113.             def write(self, buf):
  114.                 raise IOError
  115.         writer = csv.writer(BrokenFile())
  116.         self.assertRaises(IOError, writer.writerows, [['a']])
  117.         fileobj = StringIO()
  118.         writer = csv.writer(fileobj)
  119.         self.assertRaises(TypeError, writer.writerows, None)
  120.         writer.writerows([['a','b'],['c','d']])
  121.         self.assertEqual(fileobj.getvalue(), "a,b\r\nc,d\r\n")
  122.  
  123.     def _read_test(self, input, expect, **kwargs):
  124.         reader = csv.reader(input, **kwargs)
  125.         result = list(reader)
  126.         self.assertEqual(result, expect)
  127.  
  128.     def test_read_oddinputs(self):
  129.         self._read_test([], [])
  130.         self._read_test([''], [[]])
  131.         self.assertRaises(csv.Error, self._read_test,
  132.                           ['"ab"c'], None, strict = 1)
  133.         # cannot handle null bytes for the moment
  134.         self.assertRaises(csv.Error, self._read_test,
  135.                           ['ab\0c'], None, strict = 1)
  136.         self._read_test(['"ab"c'], [['abc']], doublequote = 0)
  137.  
  138.     def test_read_eol(self):
  139.         self._read_test(['a,b'], [['a','b']])
  140.         self._read_test(['a,b\n'], [['a','b']])
  141.         self._read_test(['a,b\r\n'], [['a','b']])
  142.         self._read_test(['a,b\r'], [['a','b']])
  143.         self.assertRaises(csv.Error, self._read_test, ['a,b\rc,d'], [])
  144.         self.assertRaises(csv.Error, self._read_test, ['a,b\nc,d'], [])
  145.         self.assertRaises(csv.Error, self._read_test, ['a,b\r\nc,d'], [])
  146.  
  147.     def test_read_escape(self):
  148.         self._read_test(['a,\\b,c'], [['a', '\\b', 'c']], escapechar='\\')
  149.         self._read_test(['a,b\\,c'], [['a', 'b,c']], escapechar='\\')
  150.         self._read_test(['a,"b\\,c"'], [['a', 'b,c']], escapechar='\\')
  151.         self._read_test(['a,"b,\\c"'], [['a', 'b,\\c']], escapechar='\\')
  152.         self._read_test(['a,"b,c\\""'], [['a', 'b,c"']], escapechar='\\')
  153.         self._read_test(['a,"b,c"\\'], [['a', 'b,c\\']], escapechar='\\')
  154.  
  155.     def test_read_bigfield(self):
  156.         # This exercises the buffer realloc functionality
  157.         bigstring = 'X' * 50000
  158.         bigline = '%s,%s' % (bigstring, bigstring)
  159.         self._read_test([bigline], [[bigstring, bigstring]])
  160.  
  161. class TestDialectRegistry(unittest.TestCase):
  162.     def test_registry_badargs(self):
  163.         self.assertRaises(TypeError, csv.list_dialects, None)
  164.         self.assertRaises(TypeError, csv.get_dialect)
  165.         self.assertRaises(csv.Error, csv.get_dialect, None)
  166.         self.assertRaises(csv.Error, csv.get_dialect, "nonesuch")
  167.         self.assertRaises(TypeError, csv.unregister_dialect)
  168.         self.assertRaises(csv.Error, csv.unregister_dialect, None)
  169.         self.assertRaises(csv.Error, csv.unregister_dialect, "nonesuch")
  170.         self.assertRaises(TypeError, csv.register_dialect, None)
  171.         self.assertRaises(TypeError, csv.register_dialect, None, None)
  172.         self.assertRaises(TypeError, csv.register_dialect, "nonesuch", None)
  173.         class bogus:
  174.             def __init__(self):
  175.                 raise KeyError
  176.         self.assertRaises(KeyError, csv.register_dialect, "nonesuch", bogus)
  177.  
  178.     def test_registry(self):
  179.         class myexceltsv(csv.excel):
  180.             delimiter = "\t"
  181.         name = "myexceltsv"
  182.         expected_dialects = csv.list_dialects() + [name]
  183.         expected_dialects.sort()
  184.         csv.register_dialect(name, myexceltsv)
  185.         try:
  186.             self.failUnless(isinstance(csv.get_dialect(name), myexceltsv))
  187.             got_dialects = csv.list_dialects()
  188.             got_dialects.sort()
  189.             self.assertEqual(expected_dialects, got_dialects)
  190.         finally:
  191.             csv.unregister_dialect(name)
  192.  
  193.     def test_incomplete_dialect(self):
  194.         class myexceltsv(csv.Dialect):
  195.             delimiter = "\t"
  196.         self.assertRaises(csv.Error, myexceltsv)
  197.  
  198.     def test_space_dialect(self):
  199.         class space(csv.excel):
  200.             delimiter = " "
  201.             quoting = csv.QUOTE_NONE
  202.             escapechar = "\\"
  203.  
  204.         s = StringIO("abc def\nc1ccccc1 benzene\n")
  205.         rdr = csv.reader(s, dialect=space())
  206.         self.assertEqual(rdr.next(), ["abc", "def"])
  207.         self.assertEqual(rdr.next(), ["c1ccccc1", "benzene"])
  208.  
  209.     def test_dialect_apply(self):
  210.         class testA(csv.excel):
  211.             delimiter = "\t"
  212.         class testB(csv.excel):
  213.             delimiter = ":"
  214.         class testC(csv.excel):
  215.             delimiter = "|"
  216.  
  217.         csv.register_dialect('testC', testC)
  218.         try:
  219.             fileobj = StringIO()
  220.             writer = csv.writer(fileobj)
  221.             writer.writerow([1,2,3])
  222.             self.assertEqual(fileobj.getvalue(), "1,2,3\r\n")
  223.  
  224.             fileobj = StringIO()
  225.             writer = csv.writer(fileobj, testA)
  226.             writer.writerow([1,2,3])
  227.             self.assertEqual(fileobj.getvalue(), "1\t2\t3\r\n")
  228.  
  229.             fileobj = StringIO()
  230.             writer = csv.writer(fileobj, dialect=testB())
  231.             writer.writerow([1,2,3])
  232.             self.assertEqual(fileobj.getvalue(), "1:2:3\r\n")
  233.  
  234.             fileobj = StringIO()
  235.             writer = csv.writer(fileobj, dialect='testC')
  236.             writer.writerow([1,2,3])
  237.             self.assertEqual(fileobj.getvalue(), "1|2|3\r\n")
  238.  
  239.             fileobj = StringIO()
  240.             writer = csv.writer(fileobj, dialect=testA, delimiter=';')
  241.             writer.writerow([1,2,3])
  242.             self.assertEqual(fileobj.getvalue(), "1;2;3\r\n")
  243.         finally:
  244.             csv.unregister_dialect('testC')
  245.  
  246.     def test_bad_dialect(self):
  247.         # Unknown parameter
  248.         self.assertRaises(AttributeError, csv.reader, [], bad_attr = 0)
  249.         # Bad values
  250.         self.assertRaises(TypeError, csv.reader, [], delimiter = None)
  251.         self.assertRaises(TypeError, csv.reader, [], quoting = -1)
  252.         self.assertRaises(TypeError, csv.reader, [], quoting = 100)
  253.  
  254. class TestCsvBase(unittest.TestCase):
  255.     def readerAssertEqual(self, input, expected_result):
  256.         reader = csv.reader(StringIO(input), dialect = self.dialect)
  257.         fields = list(reader)
  258.         self.assertEqual(fields, expected_result)
  259.  
  260.     def writerAssertEqual(self, input, expected_result):
  261.         fileobj = StringIO()
  262.         writer = csv.writer(fileobj, dialect = self.dialect)
  263.         writer.writerows(input)
  264.         self.assertEqual(fileobj.getvalue(), expected_result)
  265.  
  266. class TestDialectExcel(TestCsvBase):
  267.     dialect = 'excel'
  268.  
  269.     def test_single(self):
  270.         self.readerAssertEqual('abc', [['abc']])
  271.  
  272.     def test_simple(self):
  273.         self.readerAssertEqual('1,2,3,4,5', [['1','2','3','4','5']])
  274.  
  275.     def test_blankline(self):
  276.         self.readerAssertEqual('', [])
  277.  
  278.     def test_empty_fields(self):
  279.         self.readerAssertEqual(',', [['', '']])
  280.  
  281.     def test_singlequoted(self):
  282.         self.readerAssertEqual('""', [['']])
  283.  
  284.     def test_singlequoted_left_empty(self):
  285.         self.readerAssertEqual('"",', [['','']])
  286.  
  287.     def test_singlequoted_right_empty(self):
  288.         self.readerAssertEqual(',""', [['','']])
  289.  
  290.     def test_single_quoted_quote(self):
  291.         self.readerAssertEqual('""""', [['"']])
  292.  
  293.     def test_quoted_quotes(self):
  294.         self.readerAssertEqual('""""""', [['""']])
  295.  
  296.     def test_inline_quote(self):
  297.         self.readerAssertEqual('a""b', [['a""b']])
  298.  
  299.     def test_inline_quotes(self):
  300.         self.readerAssertEqual('a"b"c', [['a"b"c']])
  301.  
  302.     def test_quotes_and_more(self):
  303.         self.readerAssertEqual('"a"b', [['ab']])
  304.  
  305.     def test_lone_quote(self):
  306.         self.readerAssertEqual('a"b', [['a"b']])
  307.  
  308.     def test_quote_and_quote(self):
  309.         self.readerAssertEqual('"a" "b"', [['a "b"']])
  310.  
  311.     def test_space_and_quote(self):
  312.         self.readerAssertEqual(' "a"', [[' "a"']])
  313.  
  314.     def test_quoted(self):
  315.         self.readerAssertEqual('1,2,3,"I think, therefore I am",5,6',
  316.                                [['1', '2', '3',
  317.                                  'I think, therefore I am',
  318.                                  '5', '6']])
  319.  
  320.     def test_quoted_quote(self):
  321.         self.readerAssertEqual('1,2,3,"""I see,"" said the blind man","as he picked up his hammer and saw"',
  322.                                [['1', '2', '3',
  323.                                  '"I see," said the blind man',
  324.                                  'as he picked up his hammer and saw']])
  325.  
  326.     def test_quoted_nl(self):
  327.         input = '''\
  328. 1,2,3,"""I see,""
  329. said the blind man","as he picked up his
  330. hammer and saw"
  331. 9,8,7,6'''
  332.         self.readerAssertEqual(input,
  333.                                [['1', '2', '3',
  334.                                    '"I see,"\nsaid the blind man',
  335.                                    'as he picked up his\nhammer and saw'],
  336.                                 ['9','8','7','6']])
  337.  
  338.     def test_dubious_quote(self):
  339.         self.readerAssertEqual('12,12,1",', [['12', '12', '1"', '']])
  340.  
  341.     def test_null(self):
  342.         self.writerAssertEqual([], '')
  343.  
  344.     def test_single(self):
  345.         self.writerAssertEqual([['abc']], 'abc\r\n')
  346.  
  347.     def test_simple(self):
  348.         self.writerAssertEqual([[1, 2, 'abc', 3, 4]], '1,2,abc,3,4\r\n')
  349.  
  350.     def test_quotes(self):
  351.         self.writerAssertEqual([[1, 2, 'a"bc"', 3, 4]], '1,2,"a""bc""",3,4\r\n')
  352.  
  353.     def test_quote_fieldsep(self):
  354.         self.writerAssertEqual([['abc,def']], '"abc,def"\r\n')
  355.  
  356.     def test_newlines(self):
  357.         self.writerAssertEqual([[1, 2, 'a\nbc', 3, 4]], '1,2,"a\nbc",3,4\r\n')
  358.  
  359. class EscapedExcel(csv.excel):
  360.     quoting = csv.QUOTE_NONE
  361.     escapechar = '\\'
  362.  
  363. class TestEscapedExcel(TestCsvBase):
  364.     dialect = EscapedExcel()
  365.  
  366.     def test_escape_fieldsep(self):
  367.         self.writerAssertEqual([['abc,def']], 'abc\\,def\r\n')
  368.  
  369.     def test_read_escape_fieldsep(self):
  370.         self.readerAssertEqual('abc\\,def\r\n', [['abc,def']])
  371.  
  372. class QuotedEscapedExcel(csv.excel):
  373.     quoting = csv.QUOTE_NONNUMERIC
  374.     escapechar = '\\'
  375.  
  376. class TestQuotedEscapedExcel(TestCsvBase):
  377.     dialect = QuotedEscapedExcel()
  378.  
  379.     def test_write_escape_fieldsep(self):
  380.         self.writerAssertEqual([['abc,def']], '"abc,def"\r\n')
  381.  
  382.     def test_read_escape_fieldsep(self):
  383.         self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']])
  384.  
  385. # Disabled, pending support in csv.utils module
  386. class TestDictFields(unittest.TestCase):
  387.     ### "long" means the row is longer than the number of fieldnames
  388.     ### "short" means there are fewer elements in the row than fieldnames
  389.     def test_write_simple_dict(self):
  390.         fileobj = StringIO()
  391.         writer = csv.DictWriter(fileobj, fieldnames = ["f1", "f2", "f3"])
  392.         writer.writerow({"f1": 10, "f3": "abc"})
  393.         self.assertEqual(fileobj.getvalue(), "10,,abc\r\n")
  394.  
  395.     def test_write_no_fields(self):
  396.         fileobj = StringIO()
  397.         self.assertRaises(TypeError, csv.DictWriter, fileobj)
  398.  
  399.     def test_read_dict_fields(self):
  400.         reader = csv.DictReader(StringIO("1,2,abc\r\n"),
  401.                                 fieldnames=["f1", "f2", "f3"])
  402.         self.assertEqual(reader.next(), {"f1": '1', "f2": '2', "f3": 'abc'})
  403.  
  404.     def test_read_long(self):
  405.         reader = csv.DictReader(StringIO("1,2,abc,4,5,6\r\n"),
  406.                                 fieldnames=["f1", "f2"])
  407.         self.assertEqual(reader.next(), {"f1": '1', "f2": '2',
  408.                                          None: ["abc", "4", "5", "6"]})
  409.  
  410.     def test_read_long_with_rest(self):
  411.         reader = csv.DictReader(StringIO("1,2,abc,4,5,6\r\n"),
  412.                                 fieldnames=["f1", "f2"], restkey="_rest")
  413.         self.assertEqual(reader.next(), {"f1": '1', "f2": '2',
  414.                                          "_rest": ["abc", "4", "5", "6"]})
  415.  
  416.     def test_read_short(self):
  417.         reader = csv.DictReader(["1,2,abc,4,5,6\r\n","1,2,abc\r\n"],
  418.                                 fieldnames="1 2 3 4 5 6".split(),
  419.                                 restval="DEFAULT")
  420.         self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
  421.                                          "4": '4', "5": '5', "6": '6'})
  422.         self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
  423.                                          "4": 'DEFAULT', "5": 'DEFAULT',
  424.                                          "6": 'DEFAULT'})
  425.  
  426.     def test_read_multi(self):
  427.         sample = [
  428.             '2147483648,43.0e12,17,abc,def\r\n',
  429.             '147483648,43.0e2,17,abc,def\r\n',
  430.             '47483648,43.0,170,abc,def\r\n'
  431.             ]
  432.  
  433.         reader = csv.DictReader(sample,
  434.                                 fieldnames="i1 float i2 s1 s2".split())
  435.         self.assertEqual(reader.next(), {"i1": '2147483648',
  436.                                          "float": '43.0e12',
  437.                                          "i2": '17',
  438.                                          "s1": 'abc',
  439.                                          "s2": 'def'})
  440.  
  441.     def test_read_with_blanks(self):
  442.         reader = csv.DictReader(["1,2,abc,4,5,6\r\n","\r\n",
  443.                                  "1,2,abc,4,5,6\r\n"],
  444.                                 fieldnames="1 2 3 4 5 6".split())
  445.         self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
  446.                                          "4": '4', "5": '5', "6": '6'})
  447.         self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
  448.                                          "4": '4', "5": '5', "6": '6'})
  449.  
  450.     def test_read_semi_sep(self):
  451.         reader = csv.DictReader(["1;2;abc;4;5;6\r\n"],
  452.                                 fieldnames="1 2 3 4 5 6".split(),
  453.                                 delimiter=';')
  454.         self.assertEqual(reader.next(), {"1": '1', "2": '2', "3": 'abc',
  455.                                          "4": '4', "5": '5', "6": '6'})
  456.  
  457. class TestArrayWrites(unittest.TestCase):
  458.     def test_int_write(self):
  459.         import array
  460.         contents = [(20-i) for i in range(20)]
  461.         a = array.array('i', contents)
  462.         fileobj = StringIO()
  463.         writer = csv.writer(fileobj, dialect="excel")
  464.         writer.writerow(a)
  465.         expected = ",".join([str(i) for i in a])+"\r\n"
  466.         self.assertEqual(fileobj.getvalue(), expected)
  467.  
  468.     def test_double_write(self):
  469.         import array
  470.         contents = [(20-i)*0.1 for i in range(20)]
  471.         a = array.array('d', contents)
  472.         fileobj = StringIO()
  473.         writer = csv.writer(fileobj, dialect="excel")
  474.         writer.writerow(a)
  475.         expected = ",".join([str(i) for i in a])+"\r\n"
  476.         self.assertEqual(fileobj.getvalue(), expected)
  477.  
  478.     def test_float_write(self):
  479.         import array
  480.         contents = [(20-i)*0.1 for i in range(20)]
  481.         a = array.array('f', contents)
  482.         fileobj = StringIO()
  483.         writer = csv.writer(fileobj, dialect="excel")
  484.         writer.writerow(a)
  485.         expected = ",".join([str(i) for i in a])+"\r\n"
  486.         self.assertEqual(fileobj.getvalue(), expected)
  487.  
  488.     def test_char_write(self):
  489.         import array, string
  490.         a = array.array('c', string.letters)
  491.         fileobj = StringIO()
  492.         writer = csv.writer(fileobj, dialect="excel")
  493.         writer.writerow(a)
  494.         expected = ",".join(a)+"\r\n"
  495.         self.assertEqual(fileobj.getvalue(), expected)
  496.  
  497. class TestDialectValidity(unittest.TestCase):
  498.     def test_quoting(self):
  499.         class mydialect(csv.Dialect):
  500.             delimiter = ";"
  501.             escapechar = '\\'
  502.             doublequote = False
  503.             skipinitialspace = True
  504.             lineterminator = '\r\n'
  505.             quoting = csv.QUOTE_NONE
  506.         d = mydialect()
  507.  
  508.         mydialect.quoting = None
  509.         self.assertRaises(csv.Error, mydialect)
  510.  
  511.         mydialect.quoting = csv.QUOTE_NONE
  512.         mydialect.escapechar = None
  513.         self.assertRaises(csv.Error, mydialect)
  514.  
  515.         mydialect.doublequote = True
  516.         mydialect.quoting = csv.QUOTE_ALL
  517.         mydialect.quotechar = '"'
  518.         d = mydialect()
  519.  
  520.         mydialect.quotechar = "''"
  521.         self.assertRaises(csv.Error, mydialect)
  522.  
  523.         mydialect.quotechar = 4
  524.         self.assertRaises(csv.Error, mydialect)
  525.  
  526.     def test_delimiter(self):
  527.         class mydialect(csv.Dialect):
  528.             delimiter = ";"
  529.             escapechar = '\\'
  530.             doublequote = False
  531.             skipinitialspace = True
  532.             lineterminator = '\r\n'
  533.             quoting = csv.QUOTE_NONE
  534.         d = mydialect()
  535.  
  536.         mydialect.delimiter = ":::"
  537.         self.assertRaises(csv.Error, mydialect)
  538.  
  539.         mydialect.delimiter = 4
  540.         self.assertRaises(csv.Error, mydialect)
  541.  
  542.     def test_lineterminator(self):
  543.         class mydialect(csv.Dialect):
  544.             delimiter = ";"
  545.             escapechar = '\\'
  546.             doublequote = False
  547.             skipinitialspace = True
  548.             lineterminator = '\r\n'
  549.             quoting = csv.QUOTE_NONE
  550.         d = mydialect()
  551.  
  552.         mydialect.lineterminator = ":::"
  553.         d = mydialect()
  554.  
  555.         mydialect.lineterminator = 4
  556.         self.assertRaises(csv.Error, mydialect)
  557.  
  558.  
  559. class TestSniffer(unittest.TestCase):
  560.     sample1 = """\
  561. Harry's, Arlington Heights, IL, 2/1/03, Kimi Hayes
  562. Shark City, Glendale Heights, IL, 12/28/02, Prezence
  563. Tommy's Place, Blue Island, IL, 12/28/02, Blue Sunday/White Crow
  564. Stonecutters Seafood and Chop House, Lemont, IL, 12/19/02, Week Back
  565. """
  566.     sample2 = """\
  567. 'Harry''s':'Arlington Heights':'IL':'2/1/03':'Kimi Hayes'
  568. 'Shark City':'Glendale Heights':'IL':'12/28/02':'Prezence'
  569. 'Tommy''s Place':'Blue Island':'IL':'12/28/02':'Blue Sunday/White Crow'
  570. 'Stonecutters Seafood and Chop House':'Lemont':'IL':'12/19/02':'Week Back'
  571. """
  572.  
  573.     header = '''\
  574. "venue","city","state","date","performers"
  575. '''
  576.     sample3 = '''\
  577. 05/05/03?05/05/03?05/05/03?05/05/03?05/05/03?05/05/03
  578. 05/05/03?05/05/03?05/05/03?05/05/03?05/05/03?05/05/03
  579. 05/05/03?05/05/03?05/05/03?05/05/03?05/05/03?05/05/03
  580. '''
  581.  
  582.     sample4 = '''\
  583. 2147483648;43.0e12;17;abc;def
  584. 147483648;43.0e2;17;abc;def
  585. 47483648;43.0;170;abc;def
  586. '''
  587.  
  588.     def test_has_header(self):
  589.         sniffer = csv.Sniffer()
  590.         self.assertEqual(sniffer.has_header(self.sample1), False)
  591.         self.assertEqual(sniffer.has_header(self.header+self.sample1), True)
  592.  
  593.     def test_sniff(self):
  594.         sniffer = csv.Sniffer()
  595.         dialect = sniffer.sniff(self.sample1)
  596.         self.assertEqual(dialect.delimiter, ",")
  597.         self.assertEqual(dialect.quotechar, '"')
  598.         self.assertEqual(dialect.skipinitialspace, True)
  599.  
  600.         dialect = sniffer.sniff(self.sample2)
  601.         self.assertEqual(dialect.delimiter, ":")
  602.         self.assertEqual(dialect.quotechar, "'")
  603.         self.assertEqual(dialect.skipinitialspace, False)
  604.  
  605.     def test_delimiters(self):
  606.         sniffer = csv.Sniffer()
  607.         dialect = sniffer.sniff(self.sample3)
  608.         self.assertEqual(dialect.delimiter, "0")
  609.         dialect = sniffer.sniff(self.sample3, delimiters="?,")
  610.         self.assertEqual(dialect.delimiter, "?")
  611.         dialect = sniffer.sniff(self.sample3, delimiters="/,")
  612.         self.assertEqual(dialect.delimiter, "/")
  613.         dialect = sniffer.sniff(self.sample4)
  614.         self.assertEqual(dialect.delimiter, ";")
  615.  
  616. if not hasattr(sys, "gettotalrefcount"):
  617.     if test_support.verbose: print "*** skipping leakage tests ***"
  618. else:
  619.     class NUL:
  620.         def write(s, *args):
  621.             pass
  622.         writelines = write
  623.  
  624.     class TestLeaks(unittest.TestCase):
  625.         def test_create_read(self):
  626.             delta = 0
  627.             lastrc = sys.gettotalrefcount()
  628.             for i in xrange(20):
  629.                 gc.collect()
  630.                 self.assertEqual(gc.garbage, [])
  631.                 rc = sys.gettotalrefcount()
  632.                 csv.reader(["a,b,c\r\n"])
  633.                 csv.reader(["a,b,c\r\n"])
  634.                 csv.reader(["a,b,c\r\n"])
  635.                 delta = rc-lastrc
  636.                 lastrc = rc
  637.             # if csv.reader() leaks, last delta should be 3 or more
  638.             self.assertEqual(delta < 3, True)
  639.  
  640.         def test_create_write(self):
  641.             delta = 0
  642.             lastrc = sys.gettotalrefcount()
  643.             s = NUL()
  644.             for i in xrange(20):
  645.                 gc.collect()
  646.                 self.assertEqual(gc.garbage, [])
  647.                 rc = sys.gettotalrefcount()
  648.                 csv.writer(s)
  649.                 csv.writer(s)
  650.                 csv.writer(s)
  651.                 delta = rc-lastrc
  652.                 lastrc = rc
  653.             # if csv.writer() leaks, last delta should be 3 or more
  654.             self.assertEqual(delta < 3, True)
  655.  
  656.         def test_read(self):
  657.             delta = 0
  658.             rows = ["a,b,c\r\n"]*5
  659.             lastrc = sys.gettotalrefcount()
  660.             for i in xrange(20):
  661.                 gc.collect()
  662.                 self.assertEqual(gc.garbage, [])
  663.                 rc = sys.gettotalrefcount()
  664.                 rdr = csv.reader(rows)
  665.                 for row in rdr:
  666.                     pass
  667.                 delta = rc-lastrc
  668.                 lastrc = rc
  669.             # if reader leaks during read, delta should be 5 or more
  670.             self.assertEqual(delta < 5, True)
  671.  
  672.         def test_write(self):
  673.             delta = 0
  674.             rows = [[1,2,3]]*5
  675.             s = NUL()
  676.             lastrc = sys.gettotalrefcount()
  677.             for i in xrange(20):
  678.                 gc.collect()
  679.                 self.assertEqual(gc.garbage, [])
  680.                 rc = sys.gettotalrefcount()
  681.                 writer = csv.writer(s)
  682.                 for row in rows:
  683.                     writer.writerow(row)
  684.                 delta = rc-lastrc
  685.                 lastrc = rc
  686.             # if writer leaks during write, last delta should be 5 or more
  687.             self.assertEqual(delta < 5, True)
  688.  
  689. # commented out for now - csv module doesn't yet support Unicode
  690. if 0:
  691.     from StringIO import StringIO
  692.     import csv
  693.  
  694.     class TestUnicode(unittest.TestCase):
  695.         def test_unicode_read(self):
  696.             import codecs
  697.             f = codecs.EncodedFile(StringIO("Martin von L÷wis,"
  698.                                             "Marc AndrΘ Lemburg,"
  699.                                             "Guido van Rossum,"
  700.                                             "Franτois Pinard\r\n"),
  701.                                    data_encoding='iso-8859-1')
  702.             reader = csv.reader(f)
  703.             self.assertEqual(list(reader), [[u"Martin von L÷wis",
  704.                                              u"Marc AndrΘ Lemburg",
  705.                                              u"Guido van Rossum",
  706.                                              u"Franτois Pinardn"]])
  707.  
  708. def test_main():
  709.     mod = sys.modules[__name__]
  710.     test_support.run_unittest(
  711.         *[getattr(mod, name) for name in dir(mod) if name.startswith('Test')]
  712.     )
  713.  
  714. if __name__ == '__main__':
  715.     test_main()
  716.